package com.ev.framework.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
 * RabbitMQ 配置类
 * 注册监听队列与消费者
 */
//@Configuration
public class RabbitmqConfig {
    private static final Logger log= LoggerFactory.getLogger(RabbitmqConfig.class);

    @Autowired
    private Environment env;

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Autowired
    private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;
//    @Bean("batchQueueRabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory batchQueueRabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
//        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(1);
        factory.setMaxConcurrentConsumers(1);
        factory.setPrefetchCount(1);
        factory.setTxSize(1);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }
    /**
     * 单一消费者
     * @return
     */
//    @Bean(name = "singleListenerContainer")
    public SimpleRabbitListenerContainerFactory listenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(1);
        factory.setMaxConcurrentConsumers(1);
        factory.setPrefetchCount(1);
        factory.setTxSize(1);
        factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
        return factory;
    }

    /**
     * 多个消费者
     * @return
     */
//    @Bean(name = "multiListenerContainer")
    public SimpleRabbitListenerContainerFactory multiListenerContainer(){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factoryConfigurer.configure(factory,connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setAcknowledgeMode(AcknowledgeMode.NONE);
        factory.setConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.simple.concurrency",int.class));
        factory.setMaxConcurrentConsumers(env.getProperty("spring.rabbitmq.listener.simple.max-concurrency",int.class));
        factory.setPrefetchCount(env.getProperty("spring.rabbitmq.listener.simple.prefetch",int.class));
        return factory;
    }

//    @Bean
    public RabbitTemplate rabbitTemplate(){
        connectionFactory.setPublisherConfirms(true);
        connectionFactory.setPublisherReturns(true);
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                log.info("消息发送成功:correlationData({}),ack({}),cause({})",correlationData,ack,cause);
            }
        });
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                log.info("消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}",exchange,routingKey,replyCode,replyText,message);
            }
        });
        return rabbitTemplate;
    }

    /**************************************************************************************************************************************************
     * 消息模型模块*************************************************************************************************************************************
     **************************************************************************************************************************************************/
//    @Bean(name = "deviceDataQueue")
//    public Queue deviceDataQueue(){
//        return new Queue(env.getProperty("data.device.queue.name"),true);
//    }
//
//    @Bean
//    public DirectExchange deviceDataExchange(){
//        return new DirectExchange(env.getProperty("data.device.exchange.name"),true, false);
//    }
//
//    @Bean
//    public Binding deviceDataBinding(){
//        return BindingBuilder.bind(deviceDataQueue()).to(deviceDataExchange()).with(env.getProperty("data.device.routing.key.name"));
//    }
//
//    @Bean(name = "noticeQueue")
//    public Queue noticeQueue(){
//        return new Queue("gyhl.data.notice.queue",true);
//    }
//
//    @Bean
//    public DirectExchange noticeDataExchange(){
//        return new DirectExchange("gyhl.data.notice.exchange",true, false);
//    }
//
//    @Bean
//    public Binding noticeDataBinding(){
//        return BindingBuilder.bind(noticeQueue()).to(noticeDataExchange()).with("gyhl.data.notice.routing.key");
//    }
//
//    @Bean(name = "dbDataQueue")
//    public Queue dbDataQueue(){
//        return new Queue("gyhl.data.db.queue",true);
//    }
//
//    @Bean
//    public DirectExchange dbDataExchange(){
//        return new DirectExchange("gyhl.data.db.exchange",true, false);
//    }
//
//    @Bean
//    public Binding dbDataBinding(){
//        return BindingBuilder.bind(dbDataQueue()).to(dbDataExchange()).with("gyhl.data.db.routing.key");
//    }
//
//    @Bean(name = "deviceTreatedQueue")
//    public Queue deviceTreatedQueue(){
//        return new Queue("data.device.treated",true);
//    }
//
//    @Bean
//    public DirectExchange deviceTreatedExchange(){
//        return new DirectExchange("data.device.treated.exchange",true, false);
//    }
//
//    @Bean
//    public Binding deviceTreatedBinding(){
//        return BindingBuilder.bind(deviceTreatedQueue()).to(deviceTreatedExchange()).with("data.device.treated.routing.key");
//    }

}
